import React, { useEffect, useRef, useState } from "react";
import "./index.scss";
import {
  Tree,
  Tooltip,
  Button,
  Modal,
  Input,
  Table,
  Tag,
  message,
  Pagination,
  Empty,
} from "antd";
import type { TreeProps, InputRef } from "antd";
import Icon, {
  SwapOutlined,
  LikeOutlined,
  DislikeOutlined,
  HistoryOutlined,
  DownloadOutlined,
  FileSearchOutlined,
  LikeFilled,
  DislikeFilled,
  CloseOutlined,
  GlobalOutlined,
  StopOutlined,
  StopFilled,
  CloseCircleFilled,
} from "@ant-design/icons";
import { getI18n } from "../../i18n";

const { TextArea } = Input;

const INDEX_MAP = {
  DEFAULT: 0,
  AGREE: 1,
  DISAGREE: 2,
};

const copyStatus = 3
const replaceStatus = 4

const CopySvg = () => {
  return (
    <svg width="1em" height="1em" fill="currentColor" viewBox="0 0 1024 1024">
      <path d="M924 862a40 40 0 0 1 0-80 20 20 0 0 0 20-20V100a20 20 0 0 0-20-20H262a20 20 0 0 0-20 20 40 40 0 0 1-80 0A100 100 0 0 1 262 0h662a100 100 0 0 1 100 100v662a100 100 0 0 1-100 100z"></path>
      <path d="M762 1024H100A100 100 0 0 1 0 924V262a100 100 0 0 1 100-100h662a100 100 0 0 1 100 100v662a100 100 0 0 1-100 100zM100 242a20 20 0 0 0-20 20v662a20 20 0 0 0 20 20h662a20 20 0 0 0 20-20V262a20 20 0 0 0-20-20z"></path>
      <path d="M431 807a40 40 0 0 1-40-40V419a40 40 0 0 1 80 0v348a40 40 0 0 1-40 40z"></path>
      <path d="M605 633H257a40 40 0 0 1 0-80h348a40 40 0 0 1 0 80z"></path>
    </svg>
  );
};

const CompareSvg = () => {
  return (
    <svg width="1em" height="1em" viewBox="0 0 16 16">
      <title>对比</title>
      <g id="控件" stroke="none" fill="none">
        <g id="icon_对比">
          <rect id="矩形" x="0" y="0" width="16" height="16"></rect>
          <path
            d="M7,0 C7.27614237,-5.07265313e-17 7.5,0.223857625 7.5,0.5 L7.5,15.5 C7.5,15.7761424 7.27614237,16 7,16 C6.72385763,16 6.5,15.7761424 6.5,15.5 L6.5,15 L2.5,15 C1.72030388,15 1.07955132,14.4051119 1.00686658,13.64446 L1,13.5 L1,2.5 C1,1.72030388 1.59488808,1.07955132 2.35553999,1.00686658 L2.5,1 L6.5,1 L6.5,0.5 C6.5,0.223857625 6.72385763,5.07265313e-17 7,0 Z M6.5,14 L6.5,2 L2.5,2 C2.25454011,2 2.05039163,2.17687516 2.00805567,2.41012437 L2,2.5 L2,13.5 C2,13.7454599 2.17687516,13.9496084 2.41012437,13.9919443 L2.5,14 L6.5,14 Z"
            id="形状结合"
            fill="currentColor"
          ></path>
          <path
            d="M13.5,1 C14.2796961,1 14.9204487,1.59488808 14.9931334,2.35553999 L15,2.5 L15,13.5 C15,14.2796961 14.4051119,14.9204487 13.64446,14.9931334 L13.5,15 L10,15 C9.72385763,15 9.5,14.7761424 9.5,14.5 C9.5,14.2545401 9.67687516,14.0503916 9.91012437,14.0080557 L10,14 L13.5,14 C13.7454599,14 13.9496084,13.8231248 13.9919443,13.5898756 L14,13.5 L14,2.5 C14,2.25454011 13.8231248,2.05039163 13.5898756,2.00805567 L13.5,2 L10,2 C9.72385763,2 9.5,1.77614237 9.5,1.5 C9.5,1.25454011 9.67687516,1.05039163 9.91012437,1.00805567 L10,1 L13.5,1 Z"
            id="路径"
            fill="currentColor"
            opacity="0.449999988"
          ></path>
        </g>
      </g>
    </svg>
  );
};

const TableTag = ({ lang, status }: { lang: string; status: number }) => {
  const i18n = getI18n(lang);
  if (status === 0) {
    return (
      <Tag bordered={false} color="processing">
        {i18n.executing}
      </Tag>
    );
  } else if (status === 1) {
    return (
      <Tag bordered={false} color="success">
        {i18n.success}
      </Tag>
    );
  } else if (status === 2) {
    return (
      <Tag bordered={false} color="error">
        {i18n.failed}
      </Tag>
    );
  } else if (status === 4) {
    return (
      <Tag bordered={false} color="warning">
        {i18n.queueing}
      </Tag>
    );
  } else if (status === 5) {
    return (
      <Tag bordered={false} color="default">
        {i18n.cancle}
      </Tag>
    );
  } else {
    return (
      <Tag bordered={false} color="default">
        {i18n.timeout}
      </Tag>
    );
  }
};

const DEFAULT_PAGE = 1;
const DEFAULT_PAGE_SIZE = 10;

interface DocProps {
  lang: string;
}

const Doc: React.FC<DocProps> = ({ lang }) => {
  const [isOpen, setIsOpen] = useState(false);
  const [feedback, setFeedback] = useState<string>("");
  const [isOpenHistory, setIsOpenHistory] = useState(false);
  const [messageApi, contextHolder] = message.useMessage();
  const [likeIndex, setLikeIndex] = useState<number>(INDEX_MAP.DEFAULT);
  const inputRef = useRef<InputRef>(null);
  const [isError, setIsError] = useState<boolean>(false);
  const [page, setPage] = useState<number>(DEFAULT_PAGE);
  const [pageSize, setPageSize] = useState<number>(DEFAULT_PAGE_SIZE);
  const [total, setTotal] = useState<number>(0);
  const [dataSource, setDataSource] = useState<any[]>([]);
  const [treeData, setTreeData] = useState<any[]>([]);
  const [textInfo, setTextInfo] = useState({
    originalText: "",
    rule: "",
    reason: "",
    advice: "",
    fileName: "",
    line: "",
    defectId: "",
  });
  const [questionCount, setQuestionCount] = useState(0);
  const reportId = useRef<number>(0);
  const pageInfo = useRef({
    page: DEFAULT_PAGE,
    pageSize: DEFAULT_PAGE_SIZE,
  });
  const timer = useRef<any>(null);

  const i18n = getI18n(lang);

  useEffect(() => {
    pageInfo.current.page = page;
    pageInfo.current.pageSize = pageSize;
  }, [page, pageSize]);

  const onSelect: TreeProps["onSelect"] = (selectedKeys, info) => {
    const { node }: { node: any } = info;
    if (node?.isLeaf) {
      setTextInfo({
        originalText: node.problematicSentence,
        rule: node.ruleName,
        reason: node.reason,
        advice: node.fixedSentence,
        line: node.problematicLineNum,
        fileName: node.filePath,
        defectId: node.defectId,
      });
      if (window.vscode) {
        window.vscode.postMessage({
          type: "goToFile",
          data: {
            filePath: node.filePath,
            line: node.problematicLineNum,
          },
        });
        window.vscode.postMessage({
          type: "queryStatus",
          data: {
            defectId: node.defectId,
          },
        });
      }
    }
  };

  const viewReport = (id: number) => {
    reportId.current = id;
    if (window.vscode) {
      window.vscode.postMessage({
        type: "viewReport",
        data: id,
      });
    }
  };
  const downLoad = (id: number) => {
    reportId.current = id;
    if (window.vscode) {
      window.vscode.postMessage({
        type: "downLoad",
        data: id,
      });
    }
  };
  const cancle = (id: number) => {
    reportId.current = id;
    if (window.vscode) {
      window.vscode.postMessage({
        type: "cancel", 
        data: id,
      });
    }
  };
  
  const openOnlineReport = (id: number) => {
    if (window.vscode) {
      window.vscode.postMessage({
        type: "openExternal",
        data: id,
      });
    }
  };

  const columns: any = [
    {
      title: i18n.fileName,
      dataIndex: "localPath",
      key: "localPath",
      width: 140,
      render: (path: string) => (
        <Tooltip title={path}>
          <span>{path.split(/[\\/]/).pop() || path}</span>
        </Tooltip>
      ),
    },
    {
      title: i18n.createTime,
      dataIndex: "createTime",
      key: "createTime",
      width: 160,
    },
    {
      title: i18n.creator,
      dataIndex: "userName",
      key: "userName",
      width: 80,
      render: (userName: string) => (
        <Tooltip title={userName}>
          <span className="ellipsis">{userName}</span>
        </Tooltip>
      ),
    },
    {
      title: i18n.status,
      dataIndex: "status",
      width: 100,
      key: "status",
      render: (status: number) => {
        return <TableTag status={status} lang={lang} />;
      },
    },
    {
      title: i18n.report,
      key: "operate",
      fixed: "right",
      width: 160,
      render: (item: any) => {
        return (
          <React.Fragment>
            <Button 
              onClick={() => cancle(item.reportId)}
              disabled={item.status !== 0 && item.status !== 4}
              color="danger"
              variant="text"
              icon={<CloseOutlined />}
            >
              {i18n.cancle}
            </Button>
            <Button
              onClick={() => viewReport(item.reportId)}
              disabled={item.status !== 1}
              color="primary"
              variant="text"
              icon={<FileSearchOutlined />}
            >
              {i18n.viewReport}
            </Button>
            {/* <Button
              onClick={() => downLoad(item.reportId)}
              disabled={item.status !== 1}
              color="cyan"
              variant="text"
              icon={<DownloadOutlined />}
            >
              {i18n.download}
            </Button> */}
            <Button
              onClick={() => openOnlineReport(item.reportId)}
              disabled={item.status !== 1}
              color="primary"
              variant="text"
              icon={<GlobalOutlined />}
            >
              {i18n.viewOnlineReport}
            </Button>
          </React.Fragment>
        );
      },
    },
  ];

  const likeOnChange = () => {
    if (window.vscode) {
      const status =
        likeIndex === INDEX_MAP.AGREE ? INDEX_MAP.DEFAULT : INDEX_MAP.AGREE;
      window.vscode.postMessage({
        type: "raise",
        data: {
          status: status,
          reportId: reportId.current,
          defectId: textInfo.defectId,
        },
      });
    }
  };

  const copy = () => {
    if (
      textInfo.originalText.length > 0 &&
      textInfo.advice.length > 0 &&
      window.vscode
    ) {
      window.vscode.postMessage({
        type: "copy",
        data: textInfo.advice,
      });
      if (window.vscode) {
        window.vscode.postMessage({
          type: "raise",
            data: {
              status: copyStatus,
              reportId: reportId.current,
              defectId: textInfo.defectId,
            },
        });
      }
    }
  };

  const compare = () => {
    if (
      textInfo.originalText.length > 0 &&
      textInfo.advice.length > 0 &&
      window.vscode
    ) {
      window.vscode.postMessage({
        type: "compare",
        data: {
          filePath: textInfo.fileName,
          line: textInfo.line,
          originText: textInfo.originalText,
          fixText: textInfo.advice,
        },
      });
    }
  };

  const replace = () => {
    if (
      textInfo.originalText.length > 0 &&
      textInfo.advice.length > 0 &&
      window.vscode
    ) {
      window.vscode.postMessage({
        type: "replace",
        data: {
          filePath: textInfo.fileName,
          line: textInfo.line,
          originText: textInfo.originalText,
          fixText: textInfo.advice,
        },
      });
      if (window.vscode) {
        window.vscode.postMessage({
          type: "raise",
            data: {
              status: replaceStatus,
              reportId: reportId.current,
              defectId: textInfo.defectId,
            },
        });
      }
    }
  };

  const fetchData = (curPage: number, curPageSize: number) => {
    if (window.vscode) {
      window.vscode.postMessage({
        type: "fetchRecord",
        data: {
          page: curPage,
          pageSize: curPageSize,
        },
      });
    }
  };

  useEffect(() => {
    timer.current = setInterval(() => {
      const { page, pageSize } = pageInfo.current;
      fetchData(page, pageSize);
    }, 10000);
    return () => {
      if (timer.current) {
        clearInterval(timer.current);
      }
    };
  }, []);

  useEffect(() => {
    fetchData(1, 10);
  }, []);

  const disLikeOnChange = () => {
    if ([INDEX_MAP.DEFAULT, INDEX_MAP.AGREE].includes(likeIndex)) {
      setIsOpen(true);
      setFeedback("");
    } else {
      if (window.vscode) {
        window.vscode.postMessage({
          type: "raise",
          data: {
            status: INDEX_MAP.DEFAULT,
            reportId: reportId.current,
            defectId: textInfo.defectId,
          },
        });
      }
    }
  };

  const submitFeedback = () => {
    if (feedback.trim() === "") {
      messageApi.open({
        type: "error",
        content: i18n.feedbackErrorInfo,
      });
      if (inputRef.current) {
        inputRef.current.focus();
      }
      setIsError(true);
      return;
    }
    if (window.vscode) {
      window.vscode.postMessage({
        type: "raise",
        data: {
          status: INDEX_MAP.DISAGREE,
          reportId: reportId.current,
          defectId: textInfo.defectId,
          reason: feedback,
        },
      });
    }
    setIsOpen(false);
  };

  const textareaOnChange = (e: any) => {
    setFeedback(e.target.value);
    setIsError(false);
  };

  const toggle = () => {
    setIsOpenHistory(true);
    // Reset page info in both state and ref
    pageInfo.current = {
      page: DEFAULT_PAGE,
      pageSize: DEFAULT_PAGE_SIZE
    };
    setPage(DEFAULT_PAGE);
    setPageSize(DEFAULT_PAGE_SIZE);
    fetchData(DEFAULT_PAGE, DEFAULT_PAGE_SIZE);
  };

  useEffect(() => {
    window.addEventListener("message", (message) => {
      console.log(message)
      if (message.data.type === "copyCallback") {
        messageApi.open({
          type: "success",
          content: i18n.copySuccessful,
        });
      } else if (message.data.type === "gotoFileCallback") {
        messageApi.open({
          type: "error",
          content: i18n.fileNotExist,
        });
      } else if (message.data.type === "queryStatusCallback") {
        const { status } = message.data.data;
        setLikeIndex(status);
      } else if (message.data.type === "raiseCallback") {
        let { status } = message.data.data;
        // 如果status是copyStatus或者replaceStatus，则将status设置为INDEX_MAP.AGREE
        if (status === copyStatus) {
          status = INDEX_MAP.AGREE;
        } else if (status === replaceStatus) {
          status = INDEX_MAP.AGREE;
        }
        setLikeIndex(status);
        if (status === INDEX_MAP.DISAGREE) {
          messageApi.open({
            type: "success",
            content: i18n.submitSuccess,
          });
        }
      } else if (message.data.type === "createCheckTask") {
        if (message.data.data) {
          messageApi.open({
            type: "success",
            content: i18n.createTaskSuccess,
          });
          toggle();
          timer.current = setInterval(() => {
            const { page, pageSize } = pageInfo.current;
            fetchData(page, pageSize);
          }, 10000);
        } else {
          messageApi.open({
            type: "error",
            content: i18n.createTaskFailed,
          });
        }
      } else if (message.data.type === "fetchRecordCallback") {
        const data = message.data.data;
        setTotal(data.total);
        const records = data.records.map((x: any) => ({
          key: x.reportId,
          ...x,
        }));
        setDataSource(records);
        let flag = true;
        for (const item of records) {
          if (item.status === 0) {
            flag = false;
          }
        }
        if (flag && timer.current) {
          clearInterval(timer.current);
        }
      } else if (message.data.type === "viewReportCallback") {
        const data = message.data.data;
        setIsOpenHistory(false);
        setQuestionCount(data.defectCount);
        // 重置textInfo
        setTextInfo({
          originalText: "",
          rule: "",
          reason: "",
          advice: "",
          fileName: "",
          line: "",
          defectId: "",
        });
        const fileDefectList = data.fileDefectList || [];
        const list: any[] = [];
        let cnt: number = 1;
        for (const item of fileDefectList) {
          list.push({
            key: `${cnt}`,
            title: `${item.fileName}`,
            children: [],
          });
          if (item.ruleDefectList) {
            for (const item2 of item.ruleDefectList) {
              let children = [];
              if (item2.ruleDefectList) {
                for (const item3 of item2.ruleDefectList) {
                  cnt += 1;
                  children.push({
                    key: `${cnt}`,
                    title: `${item3.problematicSentence}(${item3.problematicLineNum})`,
                    children: [],
                    filePath: item.fileName,
                    isLeaf: true,
                    defectId: item3.defectId,
                    ...item3,
                  });
                }
              }
              cnt += 1;
              list[list.length - 1].children.push({
                key: `${cnt}`,
                title:
                  item2.defectCount > 0
                    ? `${item2.ruleName}[${item2.defectCount}]`
                    : `${item2.ruleName}`,
                children: children,
              });
            }
          }
          cnt += 1;
        }
        for (const item of list) {
          let sum = 0;
          for (const item2 of item.children) {
            sum += item2.children.length;
          }
          if (sum > 0) {
            item.title = `${item.title}[${sum}]`;
          }
        }
        setTreeData(list);
        console.log("viewReportCallback list is", list);
      } else if (message.data.type === "cancelCallback") {
        messageApi.open({
          type: "success",
          content: i18n.cancleSuccess,
        });
      }
    });
  }, []);

  const paginationOnChange = (curPage: number, curPageSize: number) => {
    // Update the ref first to ensure timer uses correct values
    pageInfo.current = {
      page: curPage,
      pageSize: curPageSize
    };
    // Then update state and fetch data
    setPage(curPage);
    setPageSize(curPageSize);
    fetchData(curPage, curPageSize);
  };

  const checkTextInfo = () => {
    const { originalText, reason, rule, advice } = textInfo;
    return originalText && reason && rule && advice;
  };

  // Custom CSS for the reject button when active
  const rejectActiveStyle = {
    color: '#ff4d4f',
    backgroundColor: 'rgba(255, 77, 79, 0.1)',
    borderRadius: '50%',
    padding: '3px'
  };

  return (
    <React.Fragment>
      <div className="doc">
        <div className="doc-title">
          <div>{i18n.total.replace("${count}", questionCount)}</div>
          <div>
            <Button
              onClick={toggle}
              color="cyan"
              variant="link"
              icon={<HistoryOutlined />}
            >
              {i18n.viewHistoryReport}
            </Button>
          </div>
        </div>
        <div>
          {treeData.length > 0 ? (
            <Tree
              showLine={true}
              className="tree"
              onSelect={onSelect}
              treeData={treeData}
              blockNode={true}
            />
          ) : (
            <Empty />
          )}
        </div>
        {checkTextInfo() ? (
          <div className="footer">
            <div className="line" style={{ margin: "16px 0" }}></div>
            <div className="s-title">{i18n.originalText}</div>
            <div className="block">{textInfo.originalText}</div>
            <div className="s-title">{i18n.rule}</div>
            <div className="block">{textInfo.rule}</div>
            <div className="s-title">{i18n.reason}</div>
            <div className="block">{textInfo.reason}</div>
            <div className="s-title">{i18n.advice}</div>
            <div className="block">
              <div>{textInfo.advice}</div>
              <div className="block-operate">
                <div>
                  <Tooltip title={i18n.compare}>
                    <Icon
                      className="btn"
                      onClick={compare}
                      component={CompareSvg}
                    />
                  </Tooltip>
                  <Tooltip title={i18n.copy}>
                    <Icon className="btn" onClick={copy} component={CopySvg} />
                  </Tooltip>
                  <Tooltip title={i18n.replace}>
                    <SwapOutlined onClick={replace} className="btn" />
                  </Tooltip>
                  <Tooltip title={i18n.disagree}>
                    {likeIndex === 2 ? 
                      <CloseCircleFilled onClick={disLikeOnChange} className="btn" style={{color: '#ff4d4f'}} /> : 
                      <CloseOutlined onClick={disLikeOnChange} className="btn" />
                    }
                  </Tooltip>
                </div>
              </div>
            </div>
          </div>
        ) : null}
      </div>
      <Modal
        title={i18n.feedback}
        open={isOpen}
        okText={i18n.submit}
        onOk={submitFeedback}
        onCancel={() => {
          setIsOpen(false);
        }}
      >
        <TextArea
          status={isError ? "error" : undefined}
          ref={inputRef}
          value={feedback}
          onChange={textareaOnChange}
          placeholder={i18n.feedbackInfo}
          autoSize={{ minRows: 3, maxRows: 5 }}
        />
      </Modal>
      <Modal
        title={i18n.checkRecord}
        open={isOpenHistory}
        width={"80%"}
        cancelButtonProps={{ size: "small" }}
        okButtonProps={{ size: "small" }}
        onOk={() => {
          setIsOpenHistory(false);
        }}
        onCancel={() => {
          setIsOpenHistory(false);
        }}
      >
        <Table
          size="small"
          scroll={{ y: 480 }}
          dataSource={dataSource}
          columns={columns}
          pagination={false}
        />
        <div className="table-page">
          <Pagination
            size="small"
            current={page}
            pageSize={pageSize}
            total={total}
            showTotal={(curTotal) =>
              i18n.totalReportCount.replace("${count}", curTotal)
            }
            showSizeChanger
            showQuickJumper
            onChange={paginationOnChange}
          />
        </div>
      </Modal>
      {contextHolder}
    </React.Fragment>
  );
};

export default Doc;
